#include "WSServer.h"
#include "WSClient.h"
#include <process.h>

using namespace std;

void WSServer::ThreadFunc( LPVOID p )
{        
    WSServer *server = (WSServer *)p;        
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2), &wsaData);
    server->m_ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    sockaddr_in service;
    service.sin_family = AF_INET;	
    service.sin_addr.s_addr = INADDR_ANY;
    service.sin_port = htons(server->m_Port);		
    if ( bind(server->m_ListenSocket, (SOCKADDR *) & service, sizeof (service)) == SOCKET_ERROR )
    {
        throw std::exception("bind socket faild");
    }

    if (listen(server->m_ListenSocket, SOMAXCONN) == SOCKET_ERROR)
    {
        throw std::exception("listen faild");
    }
    while (server->m_bCanListen) //TODO: max connections
    {
        SOCKET AcceptSocket = accept(server->m_ListenSocket, NULL, NULL);
        if (AcceptSocket)
        {
		    WSClient* client = new WSClient(AcceptSocket);		
		    server->m_RemoteClients.push_back(client);
            //
            for(WSReceiversList::iterator it = server->m_DataReceivers.begin();it != server->m_DataReceivers.end();it++)
            {
                client->SetDataReceiver(*it);
            }
        }
		// TODO: remove client when disconnected
    }    
}


WSServer::~WSServer()
{
    m_bCanListen = FALSE;
    closesocket(m_ListenSocket);
    WaitForSingleObject(m_hThread, 5000);
}

void WSServer::SetDataReceiver(WSClient::IDataReceiver *obj)
{
    m_DataReceivers.push_back(obj);
	WSClientList::iterator it = m_RemoteClients.begin();
	for(; it != m_RemoteClients.end(); it++)
	{
        if (*it != NULL) (*it)->SetDataReceiver(obj);
	}
}

WSServer::WSServer( int port ) 
{
    m_bCanListen = TRUE;
    m_Port = port;        
    m_hThread = (HANDLE)_beginthread(ThreadFunc, 0, this);    
}

void WSServer::Send( char* buffer )
{
    WSClientList::iterator it = m_RemoteClients.begin();
    for(; it != m_RemoteClients.end(); it++)
    {
        (*it)->Send(buffer);
    }  
}

void WSServer::Send( void* buffer, int len )
{
    WSClientList::iterator it = m_RemoteClients.begin();
    for(; it != m_RemoteClients.end(); it++)
    {
        (*it)->Send(buffer, len);
    }  
}
